import { computed, onMounted, ref } from 'vue'
import { defineStore } from 'pinia'
import { getLoginUserUsingGet } from '@/api/userController'

// 获取指定名称的 Cookie 值
// 注意: cookie 设置 httpsOnly=true，不能使用 document.cookie 来获取,获取的就是 null,除非后端放开限制,默认是只读的
function getCookie(name) {
  // 将当前所有 Cookies 的字符串形式前面加上 "; "。
  // 这样做的目的是为了简化后续的分割操作，避免处理 Cookie 名称前没有分号和空格的情况。
  const value = `; ${document.cookie}`

  // 使用指定的 Cookie 名称（name 参数）来分割上面构造的字符串。
  // 分割后的数组 parts，如果该 Cookie 存在，则长度应该为2：
  // 第一个元素是这个 Cookie 名称之前的所有内容，第二个元素是值以及之后的内容。
  const parts = value.split(`; ${name}=`)

  // 检查是否找到了对应的 Cookie。如果找到了（即 parts.length 为 2），则返回它的值。
  // 使用 pop() 方法获取数组的最后一个元素，即包含 Cookie 值的部分，
  // 然后使用 split(';') 方法去掉可能跟随其后的其他 Cookie 或者分号，并取第一个元素作为结果。
  if (parts.length === 2) return parts.pop().split(';').shift()
}

/**
 * 使用 Pinia 创建一个名为 `useLoginUserStore` 的 store。
 * 在 Setup Store 中：
 * - `ref()` 用于定义 state 属性。
 * - `computed()` 用于定义 getters。
 * - `function()` 用于定义 actions。
 *
 * 参考文档：https://pinia.vuejs.org/zh/core-concepts/#setup-stores
 */
export const useLoginUserStore = defineStore('useLoginUserStore', () => {
  // 定义用户信息的状态，初始值为 null 表示未登录
  const loginUser = ref<API.LoginUserVo | null>(null)

  // 定义用于存储 SESSION 和 satoken 的响应式变量
  const sessionValue = ref('')
  const saTokenValue = ref('')

  // 定义 loadAuthCookies 函数，用于加载认证 Cookie
  function loadAuthCookies() {
    // SESSION 是只读的(httpsOnly=true)所以是获取不到的,除非后端放开限制,默认是只读的
    sessionValue.value = getCookie('SESSION') || ''
    saTokenValue.value = getCookie('satoken') || ''

    console.log('SESSION:', sessionValue.value)
    console.log('satoken:', saTokenValue.value)
  }

  /**
   * 计算属性，用于判断用户是否已登录。
   * 当 `loginUser` 存在且用户名不是默认的 "未登录" 时，返回 true。
   */
  const isLogin = computed(() => !!loginUser.value && loginUser.value.userName !== '未登录')

  /**
   * 异步获取当前登录用户信息。
   * 如果请求成功并且返回的数据有效，则更新 `loginUser` 状态并保存到本地存储。
   */
  async function getLoginUser() {
    try {
      // 登录的用户信息
      const res = await getLoginUserUsingGet()
      if (res.code === 0 && res.data) {
        loginUser.value = res.data
        saveToLocalStorage() // 将用户信息保存到 localStorage

        // 获取下 cookie 信息并存储
        loadAuthCookies()
      }
    } catch (error) {
      console.error('获取登录用户失败:', error)
    }
  }

  /**
   * 登出操作，重置用户信息。
   * 清空 `loginUser` 状态，并从本地存储中移除用户信息。
   */
  function logout() {
    loginUser.value = null
    removeFromLocalStorage() // 移除本地存储中的用户信息
  }

  /**
   * 保存登录状态到 `localStorage`。
   * `localStorage` 数据不会过期，除非手动清除。
   * 注意：不要将敏感信息（如密码、令牌等）存储在 `localStorage` 中。
   */
  function saveToLocalStorage() {
    if (loginUser.value) {
      localStorage.setItem('loginUser', JSON.stringify(loginUser.value))
    }
  }

  /**
   * 从 `localStorage` 恢复登录状态。
   * 如果存在存储的用户信息，则解析并赋值给 `loginUser` 状态。
   */
  function restoreFromLocalStorage() {
    const storedUser = localStorage.getItem('loginUser')
    if (storedUser) {
      loginUser.value = JSON.parse(storedUser)
    }
  }

  /**
   * 从 `localStorage` 中移除登录状态。
   * 清除存储的用户信息，确保登出后不再保留。
   */
  function removeFromLocalStorage() {
    localStorage.removeItem('loginUser')
  }

  /**
   * 在组件挂载时尝试恢复登录状态。
   * 使用 `onMounted` 钩子确保页面加载时自动恢复用户的登录状态。
   */
  onMounted(() => {
    restoreFromLocalStorage()
    // 组件挂载时也重新加载认证信息
    loadAuthCookies()
  })

  return {
    loginUser,
    isLogin,
    getLoginUser,
    logout,
    sessionValue, // 返回 sessionValue 以便在其他地方使用
    saTokenValue, // 返回 saTokenValue 以便在其他地方使用
  }
})

/**
 * 优化: 点击刷新丢失登录状态问题
 * 关于 `localStorage` 和 `sessionStorage` 的说明：
 *
 * - `localStorage`：
 *   - 数据不会过期，除非手动清除。
 *   - 适用于需要持久化保存的信息，例如用户偏好设置或登录状态。
 *   - 注意：不要将敏感信息（如密码、令牌等）存储在 `localStorage` 中，因为它们可以通过 JavaScript 访问。
 *
 * - `sessionStorage`：
 *   - 数据仅在当前会话期间有效，关闭浏览器标签页或窗口后会被清除。
 *   - 适用于临时数据，例如购物车内容或表单草稿。
 */
